/*
    This file is part of Desu: MapleStory v62 Server Emulator
    Copyright (C) 2014  Brent Rinchiuso <brentrin@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package field;

import java.util.EnumMap;
import java.util.Map;
import util.IntegerValue;

/**
 *
 * @author Brent Rinchiuso
 */
public class MonsterStatus {

    public enum Stat implements IntegerValue {

           WEAPON_ATTACK(0x00000001),
          WEAPON_DEFENSE(0x00000002),
            MAGIC_ATTACK(0x00000004),
           MAGIC_DEFENSE(0x00000008),
           
                ACCURACY(0x00000010),
            AVOIDABILITY(0x00000020),
                   SPEED(0x00000040),
                   
        WEAPON_ATTACK_UP(0x00001000),
       WEAPON_DEFENSE_UP(0x00002000),
         MAGIC_ATTACK_UP(0x00004000),
        MAGIC_DEFENSE_UP(0x00008000),
         WEAPON_IMMUNITY(0x00040000),
          MAGIC_IMMUNITY(0x00080000),
          
          
                    STUN(0x00000080, true),
                  FREEZE(0x00000100, true),
                  POISON(0x00000200, true),
                    SEAL(0x00000400, true),
                SHOWDOWN(0x00000800, true),              
                    DOOM(0x00010000, true),
              SHADOW_WEB(0x00020000, true),
                  AMBUSH(0x00400000, true), // should be fine
                CONFUSED(0x10000000, true); // XXX check this
          
        private int value;
        private boolean debuff;

        private Stat(int val) {
            this(val, false);
        }
        
        private Stat(int val, boolean deb) {
            value = val;
            debuff = deb;
        }

        @Override
        public int getValue() {
            return value;
        }

        @Override
        public void setValue(int val) {
            this.value = val;
        }
        
        public boolean isDebuff() {
            return debuff;
        }

        public static Stat get(int value) {
            for (Stat s : values()) {
                if (s.value == value) {
                    return s;
                }
            }
            return null;
        }
    }
    private int skill;
    private int duration;
    private final EnumMap<MonsterStatus.Stat, Integer> statups;

    public MonsterStatus(int skill) {
        statups = new EnumMap<>(MonsterStatus.Stat.class);
    }

    public void setDuration(int dur) {
        duration = dur;
    }

    public int getDuration() {
        return duration;
    }

    public int getSkill() {
        return skill;
    }

    public int getStatupValue(MonsterStatus.Stat s) {
        return getStatupValue(s, 0);
    }

    public int getStatupValue(MonsterStatus.Stat s, int def) {
        if (!statups.containsKey(s)) {
            return def;
        }
        return statups.get(s);
    }

    public void addStatup(MonsterStatus.Stat s, int val) {
        if (!statups.containsKey(s)) { // this may change so we can stack
            statups.put(s, val);
        }
    }

    public int removeStatup(MonsterStatus.Stat s) {
        if (statups.containsKey(s)) {
            return statups.remove(s);
        }
        return 0;
    }

    public void subtractStatup(MonsterStatus.Stat s, int val) {
        if (statups.containsKey(s)) {
            int oVal = statups.remove(s);
            int nVal = val - oVal;
            if (nVal > 0) {
                statups.put(s, nVal);
            }
        }
    }

    public void sumStatup(MonsterStatus.Stat s, int val) {
        if (statups.containsKey(s)) {
            int oVal = statups.remove(s);
            int nVal = val + oVal;
            if (nVal > 0) {
                statups.put(s, nVal);
            }
        }
    }

    public void multiplyStatup(MonsterStatus.Stat s, int val) {
        if (statups.containsKey(s)) {
            int oVal = statups.remove(s);
            int nVal = val * oVal;
            if (nVal > 0) {
                statups.put(s, nVal);
            }
        }
    }

    public void divideStatup(MonsterStatus.Stat s, int val) {
        if (statups.containsKey(s)) {
            int oVal = statups.remove(s);
            int nVal = val / oVal;
            if (nVal > 0) {
                statups.put(s, nVal);
            }
        }
    }

    public Map<MonsterStatus.Stat, Integer> getStatups() {
        return statups;
    }

    public void clear() {
        statups.clear();
    }

    public void apply(Monster m) {
        // XXX handle buff
    }

    public void apply(Monster m, boolean foreign) {
        // XXX handle foreign buffs
    }
}
